package com.msi.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.io.File;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.Map;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import com.msi.Graph;
import com.msi.visualization.GraphVisualization;
import com.msi.visualization.MsiColor;
import com.msi.visualization.MsiColorLImpl;
import com.msi.test.*;

public class MenuAdapter {

    protected static final Logger log = Logger.getLogger(MenuAdapter.class);

    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu, submenu, toolsMenu, helpMenu;
    JMenuItem menuItem;
    JRadioButtonMenuItem rbMenuItem;
    JCheckBoxMenuItem cbMenuItem;
    JPanel parent;
    Settings settings = Settings.getInstance();

    private JFrame parentFrame;

    public MenuAdapter() {
        boolean rootIsConfigured = Logger.getRootLogger().getAllAppenders()
                .hasMoreElements();
        if (!rootIsConfigured)
            BasicConfigurator.configure();
    }

    JMenuBar createMenuBar(JPanel container) {
        parent = container;

        // Build the first menu.
        initializeMenuBar();

        String name = "Open";
        JMenuItem menuItem = createMenuItem(createListenerForOpen(), name);
        fileMenu.add(menuItem);

        String name3 = "Save";
        JMenuItem menuItem3 = createMenuItem(createListenerForSave(), name3);
        fileMenu.add(menuItem3);

        String name2 = "Generate";
        JMenuItem menuItem2 = createMenuItem(createListenerForGenerate(), name2);
        fileMenu.add(menuItem2);

        String colorName = "Compute";
        JMenuItem menuItemColor = createMenuItem(createListenerForCompute(),
                colorName);
        toolsMenu.add(menuItemColor);

        String testName = "Test";
        JMenuItem menuItemTest = createMenuItem(createListenerForTest(),
                testName);
        toolsMenu.add(menuItemTest);

        String autoLayoutName = "AutoLayout";
        JMenuItem menuItemAutoLayout = createMenuItem(
                createListenerForAutoLayout(), autoLayoutName);
        toolsMenu.add(menuItemAutoLayout);

        String infoName = "Info";
        JMenuItem menuItemInfo = createMenuItem(createListenerForInfo(),
                infoName);
        helpMenu.add(menuItemInfo);

        return menuBar;

    }

    private ActionListener createListenerForAutoLayout() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                GraphVisualization.getInstance().useAutoLayout();
            }
        };
    }

    private ActionListener createListenerForInfo() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                JOptionPane.showMessageDialog(parentFrame,
                        "\"Implementacja algorytmu CSP\"\n\n" + "Authors:\n"
                                + "Michał Kołodziejski\n" + "Karol Gałązka\n");
            }
        };
    }

    private ActionListener createListenerForTest() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                TestWindow tw = new TestWindow(parentFrame, true);
                tw.setVisible(true);
            }
        };
    }

    private ActionListener createListenerForCompute() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (GraphVisualization.getInstance().getGraph() == null)
                    return;

                MsiColor gc = new MsiColorLImpl();
                gc.setGraph(GraphVisualization.getInstance().getGraph());
                ;
                gc.color();
                GraphVisualization.getInstance().updateColors(gc);
                GraphVisualization.getInstance().repaint();

                showDialogWithResults(gc.getNumberOfColors(),
                        gc.getComputationTime());
            }
        };
    }

    private ActionListener createListenerForSave() {
        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                int returnVal = fileChooser.showSaveDialog(fileChooser);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    writeGraphToFile(GraphVisualization.getInstance()
                            .getGraph(), fileChooser.getSelectedFile());
                } else {
                    log.info("Nie wybrano zadnego pliku");
                }
                log.info("Zapisywanie pliku zakończone");
            }
        };
    }

    private void initializeMenuBar() {
        fileMenu = new JMenu("File");

        toolsMenu = new JMenu("Tools");
        helpMenu = new JMenu("Help");

        menuBar.add(fileMenu);
        menuBar.add(toolsMenu);
        menuBar.add(helpMenu);
    }

    private ActionListener createListenerForGenerate() {
        ActionListener acL = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                GenerateWindow sw = new GenerateWindow();
                sw.setVisible(true);
            }
        };

        return acL;
    };

    private ActionListener createListenerForOpen() {
        ActionListener acL = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                log.info("Rozpoczynamy wczytywanie grafu z pliku");
                JFileChooser fileChooser = createFileChooser();
                int returnVal = fileChooser.showOpenDialog(parent);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    log.info("You chose to open this file: "
                            + fileChooser.getSelectedFile());
                    Graph g = Graph
                            .createGraphByNeighbourMatrix(FileWorker
                                    .extractNeighbourList(fileChooser
                                            .getSelectedFile()));
                    Map<Integer, Point2D> map = FileWorker
                            .extractCoordinatesFromFile(fileChooser
                                    .getSelectedFile());
                    g.setCoordinates(map);
                    GraphVisualization.getInstance().buildGraph(g);
                } else {
                    log.info("Nie wybrano zadnego pliku");
                }
                log.info("Wczytywanie grafu z pliku zakończone");
            }

            private JFileChooser createFileChooser() {
                JFileChooser fileChooser = new JFileChooser();
                return fileChooser;
            }

        };
        return acL;
    }

    private void writeGraphToFile(Graph g, File result /* String name */) {
        Serializer serializer = new Persister();
        try {
            log.info(result.createNewFile());
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            serializer.write(g, result);
            System.out.println("zapisane");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void showDialogWithResults(int numberOfTables, long time) {
        JOptionPane.showMessageDialog(parentFrame, "Wyniki\n"
                + "\nLiczba stołów: " + numberOfTables + "\nCzas obliczeń: "
                + time + " milisekund");
    }

    private JMenuItem createMenuItem(ActionListener acL, String name) {
        JMenuItem menuItem = new JMenuItem(name, KeyEvent.VK_T);
        menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1,
                ActionEvent.ALT_MASK));
        menuItem.getAccessibleContext().setAccessibleDescription(
                "This doesn't really do anything");
        menuItem.addActionListener(acL);
        return menuItem;
    }

    public void setParentFrame(JFrame frame) {
        this.parentFrame = frame;
    }
}